use strict;
use warnings;

package Person;
use base qw(My::DB::Object);

use DateTime;

__PACKAGE__->meta->setup(
    table   => 'Person',
    columns => [
        'id'               => { 'type' => 'serial',    'primary_key' => 1,   'not_null' => 1 },
        'name'             => { 'type' => 'varchar',   'length'      => 255, 'not_null' => 1 },
        'family_name'      => { 'type' => 'varchar',   'length'      => 255, 'not_null' => 1 },
        'gender'           => { 'type' => 'varchar',   'length'      => 1,   'not_null' => 1 },
        'birth_date'       => { 'type' => 'datetime' },
        'birth_country_id' => { 'type' => 'varchar',   'length'      => 2,   'not_null' => 1 },
        'created'          => { 'type' => 'timestamp', 'not_null'    => 1,   'default'  => 'now' },
        'modified'         => { 'type' => 'timestamp', 'not_null'    => 1,   'default'  => 'now' },
    ],
    relationships => [
        birth_country => { type => 'one to one', class => 'Country', column_map => { 'birth_country_id' => 'id' }, },
        addresses     => {
            type        => 'one to many',
            class       => 'Contact::Address',
            column_map  => { 'id' => 'person_id' },
            add_methods => ['count'],
        },
        emails => {
            type        => 'many to many',
            map_class   => 'Contact::PersonEmailMap',
            map_from    => 'person',
            map_to      => 'email',
            add_methods => ['count'],
        },
        phones => {
            type        => 'many to many',
            map_class   => 'Contact::PersonPhoneMap',
            map_from    => 'person',
            map_to      => 'phone',
            add_methods => ['count'],
        },
    ],
);

sub set_emails {
    my $self       = shift;
    my @new_emails = @_;
    my @old_emails = $self->emails;
    my @retained_emails;

    my $active = {};
    my $old    = {};

    # for emails, the email address is the unique identifier
    foreach my $email (@new_emails) {
        $active->{ $email->address } = ( $active->{ $email->address } ? $active->{ $email->address } + 1 : 1 );
    }
    foreach my $email (@old_emails) {
        if ( !$active->{ $email->address } && $email->active && $email->owners_count == 1 ) {

            # deactivate orphaned email
            $email->active(0);
            $email->retired( DateTime->now );
            push @retained_emails, $email;
        } ## end if ( !$active->{ $email->address } && $email...
    } ## end foreach my $email (@old_emails)
    $self->emails( @retained_emails, @new_emails );
} ## end sub set_emails

sub set_phones {
    my $self       = shift;
    my @new_phones = @_;
    my @old_phones = $self->phones;
    my @retained_phones;

    my $active = {};
    my $old    = {};

    # for phones, the number is the unique identifier
    foreach my $phone (@new_phones) {
        $active->{ $phone->number } = ( $active->{ $phone->number } ? $active->{ $phone->number } + 1 : 1 );
    }
    foreach my $phone (@old_phones) {
        if ( !$active->{ $phone->number } && $phone->active && $phone->owners_count == 1 ) {

            # deactivate orphaned phone
            $phone->active(0);
            $phone->retired( DateTime->now );
            push @retained_phones, $phone;
        } ## end if ( !$active->{ $phone->number } && $phone...
    } ## end foreach my $phone (@old_phones)
    $self->phones( @retained_phones, @new_phones );
} ## end sub set_phones

sub save {
    my $self = shift;
    $self->SUPER::save( @_, 'cascade' => 1 );
}

sub delete {

    # do nothing
}

1;
